package mathive.client.panels;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

import java.util.Vector;

import mathive.client.ClientGamesData;
import mathive.client.ClientTest;
import mathive.client.PanelHandler;
import mathive.client.TestService;
import mathive.client.TestServiceAsync;
import mathive.client.UserHandler;

public class CreateTestPanel {
	private static final TestServiceAsync SERVICE = GWT.create(TestService.class);

	private VerticalPanel mainPanel = new VerticalPanel();
	private TextBox testName = new TextBox();
	private Label name_label = new Label("Test name");
	private TextBox testScore = new TextBox();
	private Label score_label = new Label("Test score");
	private Button addButton = new Button("+");
	private Button removeButton = new Button("-");
	private Button createButton = new Button("Create test");
	private VerticalPanel gamesPanel = new VerticalPanel();
	private ScrollPanel scrollPanel = new ScrollPanel(gamesPanel);
	private HorizontalPanel buttonPanel = new HorizontalPanel();
	
	private Vector<TestGamePanel> testGames = new Vector<TestGamePanel>();
	
	public CreateTestPanel() {
		scrollPanel.setSize("240px", "200px");
		// Listen for mouse events on the register button.
		createButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				ClientGamesData[] gamesData = new ClientGamesData[testGames.size()];
				for (int i = 0; i < testGames.size(); i++) {
					TestGamePanel testGame = testGames.elementAt(i);
					ClientGamesData data;
					if (testGame.getType().equals("Random")) {
						data = new ClientGamesData(
								testGame.getGame(), 
								testGame.getDifficulty(), true);
					} else {
						data = new ClientGamesData(
								testGame.getGame(), 
								testGame.getId(), false);
					}
					
					gamesData[i] = data;
				}
				
				ClientTest test = new ClientTest(
						testName.getText(),
						Integer.parseInt(testScore.getText()),
						gamesData);
				
				if (UserHandler.singleton.isOnline()) {
					SERVICE.createTest(
							UserHandler.singleton.getSessionID(),
							test,
							new CreateResponse());
				}
			}
		});
		
		addButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				TestGamePanel panel = new TestGamePanel();
				gamesPanel.add(panel);
				testGames.add(panel);
			}
		});
		
		removeButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (testGames.size() > 0) {
					gamesPanel.remove(testGames.lastElement());
					testGames.removeElementAt(testGames.size() - 1);
				}
			}
		});
		
		initialize();
	}
	
	public Widget getPanel(){
		mainPanel.clear();
		initialize();
		return mainPanel;
	}
	
	private void initialize(){
		testGames.removeAllElements();
		gamesPanel.clear();
		
		mainPanel.add(new HTML("<h1>Create Test</h1>"));
		mainPanel.add(name_label);
		testName.setText("");
		mainPanel.add(testName);
		mainPanel.add(score_label);
		testScore.setText("");
		mainPanel.add(testScore);
		mainPanel.add(scrollPanel);
		mainPanel.add(buttonPanel);
		buttonPanel.add(addButton);
		buttonPanel.add(removeButton);
		buttonPanel.add(createButton);
		
		mainPanel.setCellHorizontalAlignment(buttonPanel, HasHorizontalAlignment.ALIGN_RIGHT);
		
	}
	
	private class CreateResponse implements AsyncCallback<Boolean> {
		@Override
		public void onFailure(Throwable caught) {
		}

		@Override
		public void onSuccess(Boolean result) {
			
			if (result.booleanValue()) {
				PanelHandler.showHome();
			} else {
				mainPanel.add(new Label("ERROR"));
			}
		}
	}
	
	private class TestGamePanel extends HorizontalPanel {
		ListBox gameList = new ListBox();
		ListBox typeList = new ListBox();
		ListBox difficultyList = new ListBox();
		TextBox id = new TextBox();
		
		public TestGamePanel() {
			gameList.addItem("Sudoku");
			gameList.addItem("Minemap");
			gameList.addItem("Arithmetics");
			
			typeList.addItem("Random");
			typeList.addItem("Custom");
			
			difficultyList.addItem("Easy");
			difficultyList.addItem("Medium");
			difficultyList.addItem("Hard");
			
			id.setWidth("4em");
			
			typeList.addChangeHandler(new ChangeHandler() {
				public void onChange(ChangeEvent event) {
					if (typeList.getItemText(typeList.getSelectedIndex()).equals("Random")) {
						add(difficultyList);
						remove(id);
					} else {
						add(id);
						remove(difficultyList);
					}
				}
			});
			
			add(gameList);
			add(typeList);
			add(difficultyList);
		}
		
		public String getGame() {
			return gameList.getItemText(gameList.getSelectedIndex());
		}
		
		public String getType() {
			return typeList.getItemText(typeList.getSelectedIndex());
		}
		
		public int getDifficulty() {
			String selected = difficultyList.getItemText(difficultyList.getSelectedIndex());
			if (selected.equals("Easy")) {
				return ClientGamesData.EASY;
			} else if (selected.equals("Medium")) {
				return ClientGamesData.MEDIUM;
			} else if (selected.equals("Hard")) {
				return ClientGamesData.HARD;
			}
			return -1;
		}
		
		public int getId() {
			return Integer.parseInt(id.getText());
		}
	}
}
